﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Security.Principal;
using System.Runtime.Remoting.Messaging;
using DataTier;

namespace BusinessLogic.Security
{
    /// <summary>
    /// Информация о пользователе
    /// </summary>
    public class UserPrincipal : IPrincipal
    {
        private CustomIdentity _identity;

        public System.Security.Principal.IIdentity Identity
        {
            get { return _identity; }
        }


        public UserPrincipal(CustomIdentity identity)
        {
            _identity = identity;
        }

        public const string CALL_CONTEXT_KEY = "SecurityContext";


        #region Свойства пользователя

        public int UserId { get; set; }
        public string UserFullName { get; set; }
        public string LoginName { get; set; }
        public string UserPhone { get; set; }
        public string UserEmail { get; set; }

        public string CostCenterName { get; set; }
        public int CostCenterId { get; set; }

        public string DepartmentName { get; set; }
        public int DepartmentId { get; set; }
        public string DepartmentOfficeNumber { get; set; }

        public string JuridicalPersonName { get; set; }
        public int JuridicalPersonId { get; set; }

        public string CompanyName { get; set; }
        public int CompanyId { get; set; }
        public string CompanyAddress { get; set; }

        #endregion Свойства пользователя

        public bool DeleteAnyone { get; set; }
        public bool CreateFromOther { get; set; }
        public bool OnliIts { get; set; }
        public bool ModifOtherDocum { get; set; }
        public List<MenuItem> MenuItems { get; set; }
        public List<StateItem> StateItems { get; set; }
        public List<WebPageItem> WebPageItems { get; set; }
        

        public static UserPrincipal Current
        {
            get
            {
                UserPrincipal result;
                if (null != HttpContext.Current.User as UserPrincipal)
                {
                    result = (UserPrincipal)HttpContext.Current.User;
                }
                else
                {
                    result = CallContext.GetData(CALL_CONTEXT_KEY) as UserPrincipal;
                }
                return result;
            }
        }


        #region IPrincipal Members

        //class SimpleIdentity : IIdentity
        //{
        //    public string Name { get; set; }

        //    public string AuthenticationType { get; set; }

        //    public bool IsAuthenticated { get; set; }
        //}

        //public IIdentity Identity
        //{
        //    get
        //    {
        //        return new SimpleIdentity
        //        {
        //            Name = UserFullName,
        //            AuthenticationType = null,
        //            IsAuthenticated = UserId != -1
        //        };
        //    }
        //}

        public virtual bool IsInRole(string role)
        {
            return IsActivityAllowed(role);
        }

        #endregion


        public static UserPrincipal LoginToApplication(string DomainLoginName, string hashPassword, CustomIdentity ci)
        {
            UserPrincipal result = new UserPrincipal(ci);
            result.LoginName = DomainLoginName;
            try
            {
                ServicesClients.AuthClient client = new ServicesClients.AuthClient();
                var user = client.GetUserSecurityDetails(DomainLoginName, hashPassword);

                if (user == null)
                    throw new Exception(string.Format("Пользователь с учетной записью: {0}, не зарегистрирован в системе.", DomainLoginName));

                //// Getting user details
                result.UserId = user.User.UserId;
                result.UserFullName = user.User.FIO;
                result.LoginName = user.User.Login;
                result.UserPhone = user.User.Phone;
                result.UserEmail = user.User.Email;
                if (user.CostsCenter != null)
                {
                    result.CostCenterName = user.CostsCenter.Name;
                    result.CostCenterId = user.CostsCenter.CostsCenterId;
                }
                if (user.Department != null)
                {
                    result.DepartmentName = user.Department.Name;
                    result.DepartmentId = user.Department.DepartmentId;
                    result.DepartmentOfficeNumber = user.Department.OfficeNumber;
                }
                if (user.JuridicalPerson != null)
                {
                    result.JuridicalPersonName = user.JuridicalPerson.Name;
                    result.JuridicalPersonId = user.JuridicalPerson.JuridicalPersonId;
                }
                if (user.Company != null)
                {
                    result.CompanyName = user.Company.CompanyName;
                    result.CompanyId = user.Company.CompanyId;
                    result.CompanyAddress = user.Company.Address;
                }
                bool isEnabled = user.User.IsEnable;
                if (!isEnabled)
                    throw new Exception(string.Format("Пользователь с учетной записью: {0}, заблокирован в системе.", DomainLoginName));

                //// Getting permission items
                //if (ds.Tables.Count > 1 && ds.Tables[1] != null && ds.Tables[1].Rows != null && ds.Tables[1].Rows.Count > 0)
                //{
                //    result.AvailableActivities = ds.Tables[1].Copy();
                //}


                if (user.Role != null)
                {
                    if (user.Role.Role != null)
                    {
                        result.ModifOtherDocum = user.Role.Role.ModifOtherDocum;
                        result.OnliIts = user.Role.Role.OnlyIts;
                        result.DeleteAnyone = user.Role.Role.DeleteAnyone;
                        result.CreateFromOther = user.Role.Role.CreateFromOther;
                    }

                    // Getting menu items // Подразумевается только плоская структура Меню. Иерархию не реализовали. Стоит потом подумать про иерархию
                    if (user.Role.Menus != null && user.Role.Menus.Count() > 0)
                    {
                        result.MenuItems = new List<MenuItem>();
                        foreach (var menu in user.Role.Menus)
                        {
                            var item = new MenuItem()
                            {
                                Name = menu.Name,
                                ToolTip = menu.ToolTip,
                                Url = menu.Url
                            };
                            result.MenuItems.Add(item);
                        }
                    }

                    // Getting status permission items. Права на установку определенных статусов
                    if (user.Role.States != null && user.Role.States.Count() > 0)
                    {
                        result.StateItems = new List<StateItem>();
                        foreach (var state in user.Role.States)
                        {
                            var item = new StateItem()
                            {
                                Id = state.Id,
                                Name = state.Name,
                                Color = state.Color,
                                Description = state.Description
                            };
                            result.StateItems.Add(item);
                        }
                    }

                    // Getting status permission web-pages. Права на открытие определенных web-страниц
                    if (user.Role.WebPages != null && user.Role.WebPages.Count() > 0)
                    {
                        result.WebPageItems = new List<WebPageItem>();
                        foreach (var webPage in user.Role.WebPages)
                        {
                            var item = new WebPageItem()
                            {
                                Id = webPage.Id,
                                Name = webPage.Name,
                                Title = webPage.Title,
                                Url = webPage.Url
                            };
                            result.WebPageItems.Add(item);
                        }
                    }

                }

            }
            catch (Exception ex)
            {
                return null;
            }

            return result;
        }


        /// <summary>
        /// Аутентификация пользователя в БД
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns>1-OK, 2-пользователь заблокирован, 0-неправильный логин/пароль</returns>
        public static int AuthenticateUser(string userName, string password)
        {
            string hashPassword = String.IsNullOrEmpty(password) ? "" : PasswordMD5Helper.GetMd5Hash(password);

            ServicesClients.AuthClient client = new ServicesClients.AuthClient();
            int result = client.AuthenticateUser(userName, hashPassword);

            return result;
        }


        /// <summary>
        /// Есть ли право переводить в указанный статус у текущего пользователя
        /// </summary>
        /// <param name="stateId"></param>
        /// <returns></returns>
        public bool ExistStatePermission(int stateId)
        {
            if (Current == null || Current.StateItems == null)
                return false;

            var statePermission = Current.StateItems.Where(s => s.Id == stateId).FirstOrDefault();
            return (statePermission != null) ? true : false;
        }


        public bool IsActivityAllowed(string permissionName)
        {
            return true;


            //if (_availableActivities == null)
            //    return false;

            //DataRow[] row = _availableActivities.Select(string.Format("PERMISSION_NAME LIKE '{0}'", permissionName));

            //if (row != null && row.Count() > 0)
            //    return true;

            //return false;
        }

        public bool IsGraphAllowed(string graphName)
        {
            return true;


            //DataRow[] row = _availableActivities.Select(string.Format("GRAPH_NAME='{0}'", graphName));

            //if (row != null && row.Count() > 0)
            //    return true;

            //return false;
        }

    }
}
